//线程和进程的部分
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cmsis_os2.h"
#include "ohos_init.h"

/********************************************************************/
//连接wifi的部分
#include "wifi_connecter.h"  
#define wifi_name "jjh"
#define wifi_password "jjhjjhjjh"

/********************************************************************/

//温湿度传感器的部分
#include "aht20.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_i2c.h"
#define I2C_DATA_RATE  (400 * 1000)  // 400K

/********************************************************************/
#include <dtls_al.h>
#include <mqtt_al.h>
#include <oc_mqtt_al.h>
#include <oc_mqtt_profile.h>

//连接华为云的部分
#define CONFIG_APP_SERVERIP "117.78.5.125" //华为云设备接入标准版对接地址
#define CONFIG_APP_SERVERPORT "1883"       //不能变,MQTT接入端口为1883

#define CONFIG_APP_DEVICEID "64708e34eb2ee73fc4d39f41_hihope3861" // 替换为注册设备后生成的deviceid

#define CONFIG_APP_DEVICEPWD "hihope3861" // 替换为注册设备后生成的密钥

#define CONFIG_APP_LIFETIME 60 // seconds

#define CONFIG_QUEUE_TIMEOUT (5 * 1000)

#define MSGQUEUE_COUNT 16
#define MSGQUEUE_SIZE 10
#define CLOUD_TASK_STACK_SIZE (1024 * 10)
#define CLOUD_TASK_PRIO 24
#define BEEP_DELAY 5

/********************************************************************/
//服务和属性的部分
osMessageQueueId_t mid_MsgQueue; // message queue id
typedef enum {
    en_msg_cmd = 0, //华为云向设备发送命令
    en_msg_report,  //向华为云上传信息 
} en_msg_type_t;

typedef struct {
    osMessageQueueId_t app_msg;
    int connected;
} app_cb_t;

static app_cb_t g_app_cb;

/********************************************************************/
//向华为云推送数据
//推送数据到华为云，当需要上传数据时，需要先拼装数据，让后通过oc_mqtt_profile_propertyreport上报数据。

float temp = 0.0, humi = 0.0;//声明温湿度传感器数据

static void deal_report_msg(void)
{
    oc_mqtt_profile_service_t service;
    oc_mqtt_profile_kv_t temperature; //温度属性
    oc_mqtt_profile_kv_t humidity; //湿度属性

    if (g_app_cb.connected != 1) {
        return;
    }

    service.event_time = NULL;
    service.service_id = "Temperature_humidity"; //服务名
    service.service_property = &temperature;
    service.nxt = NULL;//下一个服务

    temperature.key = "Tem";  //服务的属性名
    temperature.value = &temp ; //上报的数据
    temperature.type = EN_OC_MQTT_PROFILE_VALUE_FLOAT; //属性是float类型，华为云平台上创建属性选择decimal(小数)
    temperature.nxt = &humidity;

    humidity.key = "Humi";  //服务的属性名
    humidity.value = &humi ; //上报的数据为"Intrude"或者是 "Safe"
    humidity.type = EN_OC_MQTT_PROFILE_VALUE_FLOAT;//属性是float类型，华为云平台上创建属性选择decimal(小数)
    humidity.nxt = NULL;

    //设备上报属性数据,用于设备按产品模型中定义的格式将属性数据上报给平台.
    oc_mqtt_profile_propertyreport(NULL, &service);
    return;
}


static int CloudMainTaskEntry(void)
{

    /***********************************************************/
    //wifi连接
    osDelay(10); /* 10 = 100ms */
    // setup your AP params
    WifiDeviceConfig apConfig = { 0 };
    strcpy(apConfig.ssid, wifi_name); // 设置wifi 名称
    strcpy(apConfig.preSharedKey, wifi_password); // 设置wifi 密码 
    apConfig.securityType = WIFI_SEC_TYPE_PSK;
    int netId = ConnectToHotspot(&apConfig);

    /***********************************************************/
    //温湿度传感器的部分
    uint32_t retval = 0;

    hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);

    hi_i2c_init(HI_I2C_IDX_0, I2C_DATA_RATE);
    retval = AHT20_Calibrate();

    /***********************************************************/
    //连接华为云的部分
    uint32_t ret;
    dtls_al_init();
    mqtt_al_init();
    oc_mqtt_init();

    g_app_cb.app_msg = osMessageQueueNew(MSGQUEUE_COUNT, MSGQUEUE_SIZE, NULL);
    if (g_app_cb.app_msg == NULL) {
        printf("Create receive msg queue failed");
    }
    oc_mqtt_profile_connect_t connect_para;
    (void)memset_s(&connect_para, sizeof(connect_para), 0, sizeof(connect_para));

    connect_para.boostrap = 0;
    connect_para.device_id = CONFIG_APP_DEVICEID;
    connect_para.device_passwd = CONFIG_APP_DEVICEPWD;
    connect_para.server_addr = CONFIG_APP_SERVERIP;
    connect_para.server_port = CONFIG_APP_SERVERPORT;
    connect_para.life_time = CONFIG_APP_LIFETIME;
    connect_para.rcvfunc = NULL;
    connect_para.security.type = EN_DTLS_AL_SECURITY_TYPE_NONE;
    ret = oc_mqtt_profile_connect(&connect_para);
    if ((ret == (int)en_oc_mqtt_err_ok)) {
        g_app_cb.connected = 1;
        printf("oc_mqtt_profile_connect succed!\r\n");
    } else {
        printf("oc_mqtt_profile_connect faild!\r\n");
    }

    /***********************************************************/
    //上报消息的部分

    deal_report_msg();
    while (1) {
        //温湿度传感器的部分
        retval = AHT20_StartMeasure();
        printf("---------------------------------------------------------\r\n");
        retval = AHT20_GetMeasureResult(&temp, &humi);
        printf("AHT20_GetMeasureResult: temp = %.2f, humi = %.2f\r\n",temp, humi);

        deal_report_msg();//上报温湿度数据

    }
    /***********************************************************/

    return 0;

}

static void IotMainTaskEntry(void)
{

    osThreadAttr_t attr;

    attr.name = "CloudMainTaskEntry";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = CLOUD_TASK_STACK_SIZE;
    attr.priority = CLOUD_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)CloudMainTaskEntry, NULL, &attr) == NULL) {
        printf("Failed to create CloudMainTaskEntry!\n");
    }
}

SYS_RUN(IotMainTaskEntry);